package kr.couponplay.android.domain.deal;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import kr.couponplay.android.ApiUrl;
import kr.couponplay.android.AppContext;
import kr.couponplay.android.domain.BaseDao;
import kr.couponplay.android.domain.DataContext;
import kr.couponplay.android.support.HttpUtils;
import kr.couponplay.android.support.LinkUtils;
import kr.couponplay.android.support.StreamUtils;
import kr.couponplay.android.support.StringUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class DealDao extends BaseDao {
	
	public DealList search(String query, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String queryParams = queryMaker(sid, 0, 0, query, offset);
			String url = ApiUrl.searchUrl + queryParams;
			String data = HttpUtils.execute(url);
			JSONArray dealsJson = new JSONObject(data).getJSONArray("deals");
			List<Deal> deals = makeDealList(sid, dealsJson);
			DataContext.lastSearchDealSize = deals.size();
			return new DealList(query, deals);
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}

	public DealListResult selectAllDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String url = ApiUrl.allDealListUrl + queryMaker(sid, mainCategoryId, subCategoryId, null, offset);
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + url;
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
				writeDataToFileCache(cacheKey, data);
			}
			
			JSONArray categoryDealsJson = new JSONObject(data).getJSONArray("categoryDeals");
			JSONArray newDealsJson = new JSONObject(data).getJSONArray("newDeals");
			JSONArray endDealsJson = new JSONObject(data).getJSONArray("endDeals");
			JSONArray freeDealsJson = new JSONObject(data).getJSONArray("freeDeals");
			
			List<Deal> categoryDeals = makeDealList(sid, categoryDealsJson);
			List<Deal> newDeals = makeDealList(sid, newDealsJson);
			List<Deal> endDeals = makeDealList(sid, endDealsJson);
			List<Deal> freeDeals = makeDealList(sid, freeDealsJson);
			
			DataContext.lastCategoryDealSize = categoryDeals.size();
			DataContext.lastNewDealSize = newDeals.size();
			DataContext.lastEndDealSize = endDeals.size();
			DataContext.lastFreeDealSize = freeDeals.size();
			
			return new DealListResult(categoryDeals, newDeals, endDeals, freeDeals);
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	public List<Deal> selectCategoryDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String queryParams = queryMaker(sid, mainCategoryId, subCategoryId, null, offset);
			String url = ApiUrl.categoryDealListUrl + queryParams;
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + ApiUrl.allDealListUrl + queryParams;
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
			}

			JSONArray categoryDealsJson = new JSONObject(data).getJSONArray("categoryDeals");
			List<Deal> categoryDeals = makeDealList(sid, categoryDealsJson);
			DataContext.lastCategoryDealSize = categoryDeals.size();
			return categoryDeals;
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	public List<Deal> selectNewDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String queryParams = queryMaker(sid, mainCategoryId, subCategoryId, null, offset);
			String url = ApiUrl.newDealListUrl + queryParams;
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + ApiUrl.allDealListUrl + queryParams;
			
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
			}
			
			JSONArray newDealsJson = new JSONObject(data).getJSONArray("newDeals");
			List<Deal> newDeals = makeDealList(sid, newDealsJson);
			DataContext.lastNewDealSize = newDeals.size();
			return newDeals;
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	public List<Deal> selectEndDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String queryParams = queryMaker(sid, mainCategoryId, subCategoryId, null, offset);
			String url = ApiUrl.endDealListUrl + queryParams;
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + ApiUrl.allDealListUrl + queryParams;
			
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
			}
			
			JSONArray endDealsJson = new JSONObject(data).getJSONArray("endDeals");
			List<Deal> endDeals = makeDealList(sid, endDealsJson);
			DataContext.lastEndDealSize = endDeals.size();
			return endDeals;
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}	
	
	public List<Deal> selectFreeDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String queryParams = queryMaker(sid, mainCategoryId, subCategoryId, null, offset);
			String url = ApiUrl.freeDealListUrl + queryParams;
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + ApiUrl.allDealListUrl + queryParams;
			
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
			}
			
			JSONArray freeDealsJson = new JSONObject(data).getJSONArray("freeDeals");
			List<Deal> freeDeals = makeDealList(sid, freeDealsJson);
			DataContext.lastFreeDealSize = freeDeals.size();
			return freeDeals;
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	public DealList selectRecentViewDeals(int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String url = ApiUrl.recentClickDealListUrl + "?sid=" + sid + "&offset=" + offset;
			String data = HttpUtils.execute(url);
			
			JSONArray jsonArray = new JSONObject(data).getJSONArray("recentClickDeals");
			List<Deal> deals = makeDealList(sid, jsonArray);
			return new DealList(deals.size(), deals);
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	public void addClickDeal(int dealId) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String url = ApiUrl.recentClickAddUrl + "?sid=" + sid + "&dealId=" + dealId;
			HttpUtils.execute(url);
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}	
	
	private String queryMaker(String sid, int mainCategoryId, int subCategoryId, String query, int offset) {
		StringBuffer queryParams = new StringBuffer();
		queryParams.append("?sid=" + StringUtils.trimToEmpty(sid));
		queryParams.append("&offset=" + offset);
		queryParams.append("&query=" + StringUtils.trimToEmpty(query));
		queryParams.append("&mainCategoryId=" + mainCategoryId);
		queryParams.append("&subCategoryId=" + subCategoryId);
		return queryParams.toString();
	}	
	
	private String readDataFromFileCache(String cacheKey) throws FileNotFoundException, IOException {
		File cacheData = getFileCache().getFile(cacheKey);

		if (cacheData.exists()) {
			return StreamUtils.streamToString(new FileInputStream(cacheData), "UTF-8");
		} else {
			getFileCache().clear();
		}
		return null;
	}
	
	private void writeDataToFileCache(String cacheKey, String data) throws FileNotFoundException, IOException {
		File cacheData = getFileCache().getFile(cacheKey);
		BufferedWriter out = new BufferedWriter(new FileWriter(cacheData));
		out.write(data, 0, data.length());
		out.close();
	}	

	private List<Deal> makeDealList(String sid, JSONArray jsonArray) throws JSONException {
		List<Deal> deals = new ArrayList<Deal>();
		
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject object = jsonArray.getJSONObject(i);
			Deal deal = new Deal();
			deal.setId(object.getInt("id"));
			deal.setCategoryId(object.getInt("categoryId"));
			deal.setTitle(object.getString("title"));
			deal.setMetaId(object.getString("metaId"));
			deal.setDiscountRate(object.getInt("discountRate"));
			deal.setNowCount(object.getInt("nowCount"));
			deal.setProvider(AppContext.getProvider(getApplicationContext(), object.getString("providerCode")));
			deal.setOriginalPrice(object.getInt("originalPrice"));
			deal.setSalesPrice(object.getInt("salesPrice"));
			deal.setFromDate(object.getString("saleStartAt"));
			deal.setToDate(object.getString("saleEndAt"));
			deal.setThumbnailImageUrl1(object.getString("imageUrl"));
			deal.setThumbnailImageUrl2(object.getString("imageUrl1"));
			deal.setDetailViewUrl(LinkUtils.landingPage(sid, deal.getId(), deal.getProvider().getCode(), deal.getMetaId()));
			deal.setViewDate(object.getString("viewDate"));
			deals.add(deal);
		}
		
		return deals;
	}
}
